package com.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(1)
@Aspect
@Component
public class HelloAspect {
    @Pointcut("execution(* com.aop.controller.AopController.hello(..))")
    public void helloWorld() {
    }

    @Before("helloWorld()")
    public void beforeMethod(JoinPoint joinPoint) {
        System.out.println("******Before method execute.");
    }

    @After("helloWorld()")
    public void afterMethod(JoinPoint joinPoint) {
        System.out.println("******After method execute.");
    }

    @AfterReturning(value = "helloWorld()", returning = "result")
    public void returnMethod(JoinPoint joinPoint, Object result) {
        System.out.println("******AfterReturning method execute.");
    }

    @AfterThrowing(value = "helloWorld()", throwing = "exception")
    public void throwMethod(Exception exception) {
        System.out.println("******AfterThrowing method execute.");
    }

    @Around("helloWorld()")
    public Object aroundMethod(ProceedingJoinPoint pjp) {
        Object result = null;
        try {
            System.out.println("======Around - before method execute.");
            result = pjp.proceed();
            System.out.println("======Around - after method execute.");
        } catch (Throwable throwable) {
            System.out.println("======Around - throw method execute.");
            throwable.printStackTrace();
        }
        System.out.println("======Around - return method execute.");
        return result;
    }
}
